/**
 * requestValidator.js - 请求验证中间件
 * 
 * 这个模块提供了使用Joi和express-validator验证请求数据的中间件。
 * 它可以验证请求体、查询参数、路径参数等。
 */

const Joi = require('joi');
const { validationResult } = require('express-validator');
const { ApiError } = require('../utils/errors');

/**
 * 使用Joi验证请求数据的中间件工厂函数
 * 
 * @param {Object} schema - Joi验证模式对象，可以包含body、query、params等属性
 * @returns {Function} Express中间件函数
 */
const validateWithJoi = (schema) => {
  return (req, res, next) => {
    const validationOptions = {
      abortEarly: false, // 返回所有错误
      allowUnknown: true, // 允许未知字段
      stripUnknown: true, // 删除未知字段
    };
    
    // 验证请求体
    if (schema.body) {
      const { error, value } = schema.body.validate(req.body, validationOptions);
      if (error) {
        return next(error);
      }
      req.body = value;
    }
    
    // 验证查询参数
    if (schema.query) {
      const { error, value } = schema.query.validate(req.query, validationOptions);
      if (error) {
        return next(error);
      }
      req.query = value;
    }
    
    // 验证路径参数
    if (schema.params) {
      const { error, value } = schema.params.validate(req.params, validationOptions);
      if (error) {
        return next(error);
      }
      req.params = value;
    }
    
    next();
  };
};

/**
 * 使用express-validator验证请求数据的中间件
 * 
 * @param {Array} validations - express-validator验证规则数组
 * @returns {Function} Express中间件函数
 */
const validate = (validations) => {
  return async (req, res, next) => {
    // 执行所有验证
    await Promise.all(validations.map(validation => validation.run(req)));
    
    // 检查验证结果
    const errors = validationResult(req);
    if (errors.isEmpty()) {
      return next();
    }
    
    // 如果有错误，创建一个ApiError并传递给错误处理中间件
    const extractedErrors = errors.array().map(err => ({
      field: err.param,
      message: err.msg,
    }));
    
    const error = new ApiError(400, '请求参数验证失败', extractedErrors);
    next(error);
  };
};

module.exports = {
  validateWithJoi,
  validate,
};